#ifndef __SF_SQLITE_HANDLER_H__
#define __SF_SQLITE_HANDLER_H__

#include "sqlite/sqlite3.h"
#include <string>
#include <vector>
using	namespace	std;


enum
{	
	XS_FAILURE	=	-1,
	XS_SUCCESS	=	0,
	XS_PARAM_NULL_POINTER	=	1,
	XS_SQLITE_OPEN_ERROR	=	2,
	XS_DB_HAS_BEEN_INITIALIZE	=	3,
	XS_SQLITE_CLOSE_ERROR	=	4,
	XS_DB_HAS_NOT_BEEN_INITIALIZE	=	5,
	XS_QUERY_DELETE_NOT_FIND	=	6,
	XS_QUREY_CREATE_ERROR	=	7,
	XS_FINALIZE_ERROR	=	7,
	XS_RESET_ERROR	=	8,
	XS_STEP_ERROR	=	9,
	XS_STEP_DONE	=	9,
	XS_STEP_ROW		=	10,
	XS_BIND_BLOB_ERROR	=	11,
	XS_BIND_LONG_ERROR	=	12,
	XS_BIND_DOUBLE_ERROR	=	13,
	XS_BIND_NULL_ERROR	=	14,
};

class CSQL_query
{

	public:

		CSQL_query ( sqlite3* _pdb, int _qh );
		~CSQL_query ();

	public:
		int		GetQh ()	{	return	m_qh;	};
		int		GetSQLiteError() { return	m_SQLite_Error; }

		int		Prepare ( const char* _pwcsQuery );
		int		Finalize ();
		int		Reset ();
		int		Step ();


		int		GetField ( long _lIndex,  char**	_ppcvalue );
		int		GetField ( long _lIndex,  int*		_plValue  );
		int		GetField ( long _lIndex,  double*	_pdValue );
		int		Getblob (long _lIndex,   const void** _ppvalue );

		int		Bind ( long	_lIndex );
		int		Bind ( long	_lindex,	int _lvalue );
		int		Bind ( long _lIndex, char* _pcvalue , int isize );
		int		Bind ( long	_lindex,	double _dvalue );
		int		Bindblob ( long _lIndex,   void* _pvalue , int isize);

	private:

		int						m_SQLite_Error;
		int						m_qh;
		sqlite3*				m_pdb;
		sqlite3_stmt*			m_pstmt;
};

class CSQLiteManager
{
	public:
		CSQLiteManager();
		~CSQLiteManager();

	public:

		int	Initialize( const char *_DBPath );

		int	UnInitialize();

		int	Query_Create	(int* _pqh,		CSQL_query** _ppq, sqlite3* _pdb = NULL );
		int	Query_Delete	(int _qh);

		int	GetLastRowid();


	private:

		int	SQLiteOpen( sqlite3** _ppdb, const char * _DBPath );
		int	SQLiteClose( sqlite3* _pdb );
		bool IsDBExist( const char *_DBPath );
		int	 CreateDB( const char *_DBPath );

		bool IsDBEffective( const char *_DBPath );

		template< typename T> 
		int	execute_sql( const char* _szsql, long _lindex, T *_Vlaue, sqlite3* _pdb = NULL );


	private:

		int			m_maxcount;
		string		m_strDBPath;
		sqlite3*	m_pdb;
		vector<CSQL_query*>		m_vec_qry;
};

template< typename T>
int CSQLiteManager::execute_sql( const char* _szsql, long _lindex, T *_Vlaue, sqlite3* _pdb )
{

	int			iRlt	=	XS_SUCCESS;
	int			qh		=	0;
	CSQL_query*	pq		=	NULL;	

	do{
		if ( NULL == _pdb )
		{
			iRlt	=  Query_Create( &qh, &pq );
		}
		else
		{
			iRlt	=  Query_Create( &qh, &pq, _pdb );
		}
		
		if( iRlt != XS_SUCCESS )				break;

		iRlt	= pq->Prepare( _szsql );
		if( iRlt != XS_SUCCESS )				break;

		iRlt	= pq->Step();
		if ( NULL != _Vlaue)
		{
			iRlt	= pq->GetField( _lindex, _Vlaue);
			if( iRlt != XS_SUCCESS )			break;
		}

		iRlt	=	Query_Delete( qh );
		if( iRlt != XS_SUCCESS )				break;

	} while ( false );	


	return	iRlt;
}





#endif
